﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using PeiYue.AuthHelper.OverWrite;
using PeiYue.Common.Helper;
using PeiYue.Common.HttpContextUser;
using PeiYue.IRepository.UnitOfWork;
using PeiYue.IServices;
using PeiYue.Model;
using PeiYue.Model.Models;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using PeiYue.Model.Dto.User;
using System.Linq.Expressions;
using PeiYue.IServices.Sys;
using AutoMapper;
using PeiYue.Api.Controllers.BASE;
using PeiYue.IServices.Purchase;
using PeiYue.IServices.Tms;
using PeiYue.IServices.Crm;

namespace PeiYue.Controllers
{
    /// <summary>
    /// 用户管理
    /// </summary>
    [Route("api/[controller]/[action]")]
    [ApiController]
    [Authorize(Permissions.Name)]
    public class UserController : BaseController<sysUserInfo>
    {
        readonly IMapper _mapper;
        private readonly IUnitOfWork _unitOfWork;
        readonly ISysUserInfoServices _sysUserInfoServices;
        readonly IUserRoleServices _userRoleServices;
        readonly IRoleServices _roleServices;
        private readonly IUser _user;
        private readonly ILogger<UserController> _logger;
        readonly IDepartmentServices _departmentServices;
        readonly IDicHeaderService _dicHeaderServices;
        readonly ISupplierServices _supplierServices;
        readonly IDriverServices _driverServices;
        readonly IShopServices _shopServices;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="unitOfWork"></param>
        /// <param name="sysUserInfoServices"></param>
        /// <param name="userRoleServices"></param>
        /// <param name="roleServices"></param>
        /// <param name="user"></param>
        /// <param name="logger"></param>
        public UserController(IUnitOfWork unitOfWork, ISysUserInfoServices sysUserInfoServices, IUserRoleServices userRoleServices, IRoleServices roleServices, IUser user, ILogger<UserController> logger, IDepartmentServices departmentServices, IDicHeaderService dicHeaderServices, ISupplierServices supplierServices, IDriverServices driverServices, IShopServices shopServices, IMapper mapper) : base(sysUserInfoServices, user)
        {
            _unitOfWork = unitOfWork;
            _sysUserInfoServices = sysUserInfoServices;
            _userRoleServices = userRoleServices;
            _roleServices = roleServices;
            _user = user;
            _logger = logger;
            _departmentServices = departmentServices;
            _dicHeaderServices = dicHeaderServices;
            _supplierServices = supplierServices;
            _driverServices = driverServices;
            _shopServices = shopServices;
            this._mapper = mapper;
        }

        /// <summary>
        /// 获取全部用户
        /// </summary>
        /// <param name="page"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        // GET: api/User
        [HttpGet]
        public async Task<MessageModel<PageModel<sysUserInfoDto>>> Get([FromQuery] SearchUserDto querymodel)
        {
            Expression<Func<sysUserInfo, bool>> ex = t => true;

            if (!string.IsNullOrEmpty(querymodel.login_name))
                ex = ex.And(t => t.uLoginName.Contains(querymodel.login_name));
            if (!string.IsNullOrEmpty(querymodel.name))
                ex = ex.And(t => t.uRealName.Contains(querymodel.name));
            if (querymodel.department_id > 0)
                ex = ex.And(t => t.department_id == querymodel.department_id);
            if (querymodel.types > 0)
                ex = ex.And(t => t.types == querymodel.types);
            if (querymodel.status == null || querymodel.status == 0)
                ex = ex.And(t => t.uStatus != 3);
            else
                ex = ex.And(t => t.uStatus == querymodel.status);

            var data = await _sysUserInfoServices.QueryPage(ex, querymodel.pageIndex, querymodel.pageSize, " Id desc ");

            #region MyRegion

            var sysUserInfos = data.data;
            // 这里可以封装到多表查询，此处简单处理
            var allUserRoles = await _userRoleServices.Query(d => d.IsDeleted == false);
            var allRoles = await _roleServices.Query(d => d.Status == 1);
            var allDepart = await _departmentServices.Query();
            var allTypes = (await _dicHeaderServices.GetDicHeader("user_types")).ToSelectList();

            var shopIds = sysUserInfos.Where(i => i.types == 20).ToList().Select(i => i.res_id).Distinct();//客户:20
            var allShop = await _shopServices.QueryByIDs(shopIds);
            var supIds = sysUserInfos.Where(i => i.types == 30).ToList().Select(i => i.res_id).Distinct();//供货商:30
            var allSupplier = await _supplierServices.QueryByIDs(supIds);
            var driverIds = sysUserInfos.Where(i => i.types == 130).ToList().Select(i => i.res_id).Distinct();//司机:130
            var allDriver = await _driverServices.QueryByIDs(driverIds);

            var users = sysUserInfos.Select(d => d.create_user).ToList().Union(sysUserInfos.Select(d => d.update_user).ToList()).Distinct().ToArray();

            var allUsers = await _sysUserInfoServices.QueryByIDs(users);
            List<sysUserInfoDto> dao = new List<sysUserInfoDto>();
            dao = _mapper.Map<List<sysUserInfoDto>>(sysUserInfos);

            foreach (var item in dao)
            {
                var currentUserRoles = allUserRoles.Where(d => d.UserId == item.uID).Select(d => d.RoleId).ToList();
                item.RIDs = currentUserRoles;
                item.RoleNames = allRoles.Where(d => currentUserRoles.Contains(d.Id)).Select(d => d.Name).ToList();
                item.DepartmentName = allDepart.Where(d => d.id == item.department_id).FirstOrDefault()?.names;
                item.TypeName = allTypes.Where(d => d.Id == item.types).FirstOrDefault()?.Name;
                item.create_names = allUsers.Where(u => u.uID == item.create_user).FirstOrDefault()?.uRealName;
                item.update_names = allUsers.Where(u => u.uID == item.update_user).FirstOrDefault()?.uRealName;

                if (item.types == 20) item.res_name = allShop.Where(i => i.id == item.res_id).FirstOrDefault()?.names;
                if (item.types == 30) item.res_name = allSupplier.Where(i => i.id == item.res_id).FirstOrDefault()?.names;
                if (item.types == 130) item.res_name = allDriver.Where(i => i.id == item.res_id).FirstOrDefault()?.names;

            }

            #endregion
            return new MessageModel<PageModel<sysUserInfoDto>>()
            {
                msg = "获取成功",
                success = data.dataCount >= 0,
                response = new PageModel<sysUserInfoDto>() { data = dao, PageSize = data.PageSize, dataCount = data.dataCount, page = data.page, pageCount = data.pageCount }
            };

        }



        /// <summary>
        /// 保存
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<MessageModel<string>> Save([FromBody] sysUserInfoDto model)
        {
            var data = new MessageModel<string>() { success = false };
            try
            {
                var dao = _mapper.Map<sysUserInfo>(model);
                dao.update_user = _user.ID;
                dao.create_user = _user.ID;
                dao.uUpdateTime = DateTime.Now;
                _unitOfWork.BeginTran();
                if (model.uID > 0)
                { // 无论 Update Or Add , 先删除当前用户的全部 U_R 关系
                    var usreroles = (await _userRoleServices.Query(d => d.UserId == dao.uID)).Select(d => d.Id.ToString()).ToArray();
                    if (usreroles.Count() > 0)
                        await _userRoleServices.DeleteByIds(usreroles);
                    if (model.RIDs.Count() > 0)
                    {
                        // 然后再执行添加操作
                        var userRolsAdd = new List<UserRole>();
                        model.RIDs.ForEach(rid => { userRolsAdd.Add(new UserRole(model.uID, rid)); });
                        await _userRoleServices.Add(userRolsAdd);
                    }
                    data.success = await _sysUserInfoServices.Update(dao, null, new List<string> { "uLoginName", "uLoginPWD", "create_time", "create_user" });
                }
                else
                {

                    var logNames = await _sysUserInfoServices.Query(i => i.uLoginName == model.uLoginName);
                    if (logNames.Count() > 0)
                    { data.status = 301; data.msg = "登录名 " + model.uLoginName + " 已存在!"; }
                    else
                    {
                        dao.uLoginPWD = MD5Helper.MD5Encrypt32("123456");
                        dao.create_user = _user.ID;
                        dao.uCreateTime = DateTime.Now;
                        dao.uID = await _sysUserInfoServices.Add(dao);
                        if (model.RIDs.Count() > 0)
                        {
                            var userRolsAdd = new List<UserRole>();
                            model.RIDs.ForEach(rid => { userRolsAdd.Add(new UserRole(dao.uID, rid)); });
                            await _userRoleServices.Add(userRolsAdd);
                        }
                        data.success = dao.uID > 0;
                    }
                }

                if (data.success)
                {
                    _unitOfWork.CommitTran();
                    data.msg = "保存成功";
                    data.response = dao?.uID.ObjToString();
                }
                return data;
            }
            catch (Exception e)
            {
                _unitOfWork.RollbackTran();
                _logger.LogError(e, e.Message);
                return data;
            }
        }


        /// <summary>
        /// 保存
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<MessageModel<string>> ResetPWD(sysUserInfoDto model)
        {
            sysUserInfo user = new sysUserInfo() { uID = model.uID, uLoginPWD = MD5Helper.MD5Encrypt32("123456"), update_user = _user.ID, uUpdateTime = DateTime.Now };
            var data = new MessageModel<string>() { success = false };
            if (model.uID > 0)
                data.success = await _sysUserInfoServices.Update(user, new List<string> { "uLoginPWD", "update_user", "uUpdateTime" }, null);

            if (data.success)
            {
                data.msg = "成功";
            }
            return data;
        }


        // GET: api/User/5
        /// <summary>
        /// 获取用户详情根据token
        /// 【无权限】
        /// </summary>
        /// <param name="token">令牌</param>
        /// <returns></returns>
        [HttpGet]
        [AllowAnonymous]
        public async Task<MessageModel<sysUserInfo>> GetInfoByToken(string token)
        {
            var data = new MessageModel<sysUserInfo>();
            if (!string.IsNullOrEmpty(token))
            {
                var tokenModel = JwtHelper.SerializeJwt(token);
                if (tokenModel != null && tokenModel.Uid > 0)
                {
                    var userinfo = await _sysUserInfoServices.QueryById(tokenModel.Uid);
                    if (userinfo != null)
                    {
                        data.response = userinfo;
                        data.success = true;
                        data.msg = "获取成功";
                    }
                }

            }
            return data;
        }


        //// GET: api/User/5
        //[HttpGet("{id}")]
        //[AllowAnonymous]
        //public string Get(string id)
        //{
        //    _logger.LogError("test wrong");
        //    return "value";
        //}

        // GET: api/User/5
        /// <summary>
        /// 获取用户详情根据token
        /// 【无权限】
        /// </summary>
        /// <param name="token">令牌</param>
        /// <returns></returns>
        //[HttpGet]
        //[AllowAnonymous]
        //public async Task<MessageModel<sysUserInfo>> GetInfoByToken(string token)
        //{
        //    var data = new MessageModel<sysUserInfo>();
        //    if (!string.IsNullOrEmpty(token))
        //    {
        //        var tokenModel = JwtHelper.SerializeJwt(token);
        //        if (tokenModel != null && tokenModel.Uid > 0)
        //        {
        //            var userinfo = await _sysUserInfoServices.QueryById(tokenModel.Uid);
        //            if (userinfo != null)
        //            {
        //                data.response = userinfo;
        //                data.success = true;
        //                data.msg = "获取成功";
        //            }
        //        }

        //    }
        //    return data;
        //}

        ///// <summary>
        ///// 添加一个用户
        ///// </summary>
        ///// <param name="sysUserInfo"></param>
        ///// <returns></returns>
        //// POST: api/User
        //[HttpPost]
        //public async Task<MessageModel<string>> Post([FromBody] sysUserInfo sysUserInfo)
        //{
        //    var data = new MessageModel<string>();

        //    sysUserInfo.uLoginPWD = MD5Helper.MD5Encrypt32(sysUserInfo.uLoginPWD);
        //    sysUserInfo.uRemark = _user.Name;

        //    var id = await _sysUserInfoServices.Add(sysUserInfo);
        //    data.success = id > 0;
        //    if (data.success)
        //    {
        //        data.response = id.ObjToString();
        //        data.msg = "添加成功";
        //    }

        //    return data;
        //}

        ///// <summary>
        ///// 更新用户与角色
        ///// </summary>
        ///// <param name="sysUserInfo"></param>
        ///// <returns></returns>
        //// PUT: api/User/5
        //[HttpPut]
        //public async Task<MessageModel<string>> Put([FromBody] sysUserInfo sysUserInfo)
        //{
        //    // 这里使用事务处理

        //    var data = new MessageModel<string>();
        //    try
        //    {
        //        _unitOfWork.BeginTran();

        //        if (sysUserInfo != null && sysUserInfo.uID > 0)
        //        {
        //            if (sysUserInfo.RIDs.Count > 0)
        //            {
        //                // 无论 Update Or Add , 先删除当前用户的全部 U_R 关系
        //                var usreroles = (await _userRoleServices.Query(d => d.UserId == sysUserInfo.uID)).Select(d => d.Id.ToString()).ToArray();
        //                if (usreroles.Count() > 0)
        //                {
        //                    var isAllDeleted = await _userRoleServices.DeleteByIds(usreroles);
        //                }

        //                // 然后再执行添加操作
        //                var userRolsAdd = new List<UserRole>();
        //                sysUserInfo.RIDs.ForEach(rid =>
        //               {
        //                   userRolsAdd.Add(new UserRole(sysUserInfo.uID, rid));
        //               });

        //                await _userRoleServices.Add(userRolsAdd);

        //            }

        //            data.success = await _sysUserInfoServices.Update(sysUserInfo);

        //            _unitOfWork.CommitTran();

        //            if (data.success)
        //            {
        //                data.msg = "更新成功";
        //                data.response = sysUserInfo?.uID.ObjToString();
        //            }
        //        }
        //    }
        //    catch (Exception e)
        //    {
        //        _unitOfWork.RollbackTran();
        //        _logger.LogError(e, e.Message);
        //    }

        //    return data;
        //}

        /// <summary>
        /// 删除用户
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        // DELETE: api/ApiWithActions/5
        //[HttpDelete]
        //public async Task<MessageModel<string>> Delete(int id)
        //{
        //    var data = new MessageModel<string>();
        //    if (id > 0)
        //    {
        //        var userDetail = await _sysUserInfoServices.QueryById(id);
        //        userDetail.tdIsDelete = true;
        //        data.success = await _sysUserInfoServices.Update(userDetail);
        //        if (data.success)
        //        {
        //            data.msg = "删除成功";
        //            data.response = userDetail?.uID.ObjToString();
        //        }
        //    }

        //    return data;
        //}
    }
}
